import "./quill-helpers";
import {
  useReactive,
  useDebounceFn,
  useMemoizedFn,
  useMount,
  useSafeState,
} from "ahooks";
import { SyntheticEvent, useContext, useRef } from "react";
import Quill, { Range } from "quill";
import { getValueOrDie } from "@common/utils";
import { GlobalModel } from "@/ui/context";
import { BrowserSession, XHSUser } from "@common/models";
import { XHSComment } from "@common/models/xhs/notes";
import Keyboard from "quill/modules/keyboard";
import events from "@/ui/events";
import emojiNames from "@/assets/emoji/emoji-names.json";
import type { Poster } from "@/ui/cpts/biz/XHSTalks/meta";

export interface Props {
  disabled?: boolean;
  disableTip?: string;
  owner: XHSUser;
  commentToReply?: XHSComment;
  onCancelReplyToClick?: () => void;
  onSendClick?: Poster;
  loading?: boolean;
  onSendAsChange?: (sendAs: XHSUser) => void;
}

export function useViewModel(props: Props) {
  const {
    owner,
    commentToReply,
    onCancelReplyToClick,
    onSendClick,
    onSendAsChange,
  } = props;
  const [editorId] = useSafeState(`editor_${Date.now()}`);
  const quillRef = useRef<Quill>();
  const globalModal = getValueOrDie(useContext(GlobalModel));
  const [sendAs, setSendAs] = useSafeState<BrowserSession>(() =>
    getValueOrDie(
      globalModal.sessions.find(
        (s) => s.apps.xhs.user?.user_id === owner.user_id,
      ),
    ),
  );
  const quillStates = useReactive({
    quickMsgStart: 0,
    curIndex: 0,
  });
  const cleaners = useRef<Array<() => void>>([]);

  const init = useDebounceFn(
    () => {
      if (quillRef.current) {
        return;
      }

      const selectFirstQuickMsg = (range: Range) => {
        globalModal.quickMessageInput = "";
        globalModal.inputMode = "normal";
        const inputRange: Range = {
          index: quillStates.quickMsgStart,
          length: range.index - quillStates.quickMsgStart,
        };
        let shortcut = quill.getText(inputRange);
        quill.deleteText(inputRange);
        if (shortcut === "/") {
          quill.insertText(range.index - 1, "/");
        } else {
          shortcut = shortcut.slice(1);
          const records = globalModal.quickMessages;
          const record = records.find((r) => r.shortcut === shortcut);
          if (record) {
            quill.insertText(inputRange.index, record.content);
          } else {
            for (const record of records) {
              if (record.shortcut.startsWith(shortcut)) {
                quill.insertText(inputRange.index, record.content);
                return;
              }
            }
            for (const record of records) {
              if (record.shortcut.includes(shortcut)) {
                quill.insertText(inputRange.index, record.content);
                return;
              }
            }
          }
        }
      };

      const quill = new Quill(`#${editorId}`, {
        theme: "snow",
        placeholder: "按 / 快速输入话术库内容",
        modules: {
          toolbar: false,
          keyboard: {
            bindings: {
              quickMessageA: {
                key: "/",
                handler: (range) => {
                  if (range.length) {
                    quill.deleteText(range);
                  }

                  if (globalModal.inputMode === "normal") {
                    globalModal.inputMode = "quick-message";
                    quillStates.quickMsgStart = range.index;
                    quillStates.curIndex = range.index;
                    quill.insertText(range.index, "/", {
                      color: "#1068da",
                      italic: true,
                    });
                  } else {
                    selectFirstQuickMsg(range);
                  }
                },
              },
              quickMessageB: {
                key: "Enter",
                handler: (range) => {
                  if (globalModal.inputMode === "normal") {
                    onSendBtnClick();
                  } else {
                    selectFirstQuickMsg(range);
                  }
                },
              },
              qmBackspace: {
                key: "Backspace",
                handler: (range) => {
                  if (globalModal.inputMode !== "quick-message") return true;

                  if (range.index === quillStates.quickMsgStart + 1) {
                    delete globalModal.quickMessageInput;
                    globalModal.inputMode = "normal";
                    quill.deleteText(
                      quillStates.quickMsgStart,
                      range.index - quillStates.quickMsgStart - 1,
                    );
                  }
                  return true;
                },
              },
            },
          } as Keyboard["options"],
        },
      });
      quillRef.current = quill;

      quill.keyboard.addBinding({
        key: ["ArrowDown", "ArrowUp", "ArrowRight", "ArrowLeft"],
        handler: () => {
          if (globalModal.inputMode !== "quick-message") return true;

          // 禁止方向键移动光标
        },
      });

      quill.on("text-change", () => {
        if (globalModal.inputMode !== "quick-message") return;
        const selection = quill.getSelection(true);
        globalModal.quickMessageInput = quill.getText(
          quillStates.quickMsgStart + 1,
          selection.index - quillStates.quickMsgStart - 1,
        );
      });
      quill.on("selection-change", (range) => {
        if (globalModal.inputMode !== "quick-message") return;

        quillStates.curIndex = range.index;
      });
      quill.root.addEventListener("blur", () => {
        if (globalModal.inputMode !== "quick-message") return;
        globalModal.inputMode = "normal";
        const len = quillStates.curIndex - quillStates.quickMsgStart;
        const inputRange: Range = {
          index: quillStates.quickMsgStart,
          length: !len ? 1 : len,
        };
        quill.deleteText(inputRange);
      });

      cleaners.current.push(
        events.QuickMessage.Select.on(({ record }) => {
          if (globalModal.inputMode !== "quick-message") return;
          globalModal.inputMode = "normal";
          globalModal.quickMessageInput = "";

          const selection = quill.getSelection(true);
          quill.deleteText({
            index: quillStates.quickMsgStart,
            length: selection.index - quillStates.quickMsgStart,
          });
          quill.insertText(quillStates.quickMsgStart, record.content);
        }),
      );
    },
    { leading: true, trailing: false },
  );

  const onSendBtnClick = useMemoizedFn(() => {
    const quill = getValueOrDie(quillRef.current);
    const content = quill
      .getContents()
      .ops.reduce((ans, cur) => {
        if (typeof cur.insert === "string") {
          ans.push(cur.insert);
        } else if (Reflect.get(cur.insert ?? {}, "emoji")) {
          ans.push(`[${Reflect.get(cur.attributes ?? {}, "emoji")}]`);
        }
        return ans;
      }, [] as string[])
      .join("");
    if (onSendClick && content) {
      onSendClick(content, sendAs);
    }
    quillRef.current?.setText("");
  });
  const onEmojiClick = useMemoizedFn(
    (e: SyntheticEvent<HTMLImageElement, MouseEvent>) => {
      const quill = getValueOrDie(quillRef.current);
      const range = quill.getSelection(true);
      const name = e.currentTarget.dataset["name"];
      quill.insertEmbed(
        range.index,
        "emoji",
        `/statics/assets/emoji/emoji-imgs/${name}.png`,
      );
      quill.setSelection(range.index, 1);
      quill.format("emoji", name);
      quill.format("width", 14);
      quill.format("height", 14);
      quill.format("alt", name);
      quill.setSelection(range.index + 1);
      console.log(quill.getContents());
    },
  );

  const setSendAsUser = useMemoizedFn((s: BrowserSession) => {
    setSendAs(s);
    if (onSendAsChange) {
      onSendAsChange(getValueOrDie(s.apps.xhs.user));
    }
  });

  useMount(init.run);

  return {
    commentToReply,
    globalModal,
    sendAs,
    editorId,
    emojiNames,

    setSendAs: setSendAsUser,
    onSendBtnClick,
    onCancelReplyToClick,
    onEmojiClick,
  };
}
